package com.example.springbootdemo.controller;


import com.example.springbootdemo.bean.core.HubConnectionManager;
import com.example.springbootdemo.bean.core.ThreadPoolManager;
import com.example.springbootdemo.dto.comparefile.ResultData;
import com.example.springbootdemo.dto.comparefile.ThingHistoryFileData;
import com.example.springbootdemo.dto.comparefile.ThingHistoryFileObj;
import com.example.springbootdemo.dto.project.JinhuaProjectDto;
import com.example.springbootdemo.dto.project.ProjectResultObj;
import com.example.springbootdemo.dto.project.ThingProjectData;
import com.example.springbootdemo.service.HistoryService;
import com.example.springbootdemo.service.ProjectService;
import com.example.springbootdemo.utils.R;
import com.example.springbootdemo.utils.ReadFileUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.text.similarity.JaccardSimilarity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

@RestController
@RequestMapping("compare")
@RequiredArgsConstructor
@Slf4j
public class CompareController {

    @Autowired
    HistoryService historyService;

    @Autowired
    ProjectService projectService;

    @Autowired
    HubConnectionManager hubConnectionManager;

    @Value("${text.compare.temp-path}")
    private String tempPath;
//    private static final String UPLOAD_DIR = "D:\\temp"; // 替换为你的目标目录
//    private static final String UPLOAD_DIR = "/home/wwwroot/comparefile.cm//temp"; // 替换为你的目标目录

    /**
     * 通用上传请求（单个）
     */
    @PostMapping("/upload")
    public R uploadFile(MultipartFile file) throws Exception
    {
//        long startTime = System.currentTimeMillis();
        try {
            String fileName = file.getOriginalFilename();

            // 构建目标文件路径
            String targetFilePath = tempPath + File.separator + fileName;
            File targetFile = new File(targetFilePath);
            if (!targetFile.exists()){
                targetFile.mkdirs();
            }

            // 将文件保存到目标目录
            file.transferTo(targetFile);

            String s = ReadFileUtil.readFile(new File(targetFilePath));



            //读取文件内容记录表单
            ResultData ajnHistoryList = historyService.getAJNHistoryList();
            ThingHistoryFileObj data = ajnHistoryList.getData();
            List<ThingHistoryFileData> historyFileDataList = data.getData();
            ThreadPoolManager threadPoolManager = ThreadPoolManager.getInstance();
            List<Callable<JinhuaProjectDto>> tasks = new ArrayList<>();
            List<JinhuaProjectDto> sortedSet = new ArrayList<>();
            JaccardSimilarity jaccardSimilarity = new JaccardSimilarity();

            for (ThingHistoryFileData item:historyFileDataList){
                if (null==item.getProjectId()){
                    continue;
                }
                Callable<JinhuaProjectDto> task = () ->{
                    Double apply = jaccardSimilarity.apply(item.getFileContent(), s);
                    JinhuaProjectDto jinhuaProjectDto = new JinhuaProjectDto();
                    jinhuaProjectDto.setProjectId(item.getProjectId());
                    jinhuaProjectDto.setSimilarityScale(apply);

                    return jinhuaProjectDto;
                };
                tasks.add(task);

            }
            List<Future<JinhuaProjectDto>> futures = threadPoolManager.submitTasks(tasks);
            //找到其中最大的三个，进行查询赋值即可
            List<JinhuaProjectDto> results = futures.stream()
                    .map(future -> {
                        try {
                            return future.get();
                        } catch (Exception e) {
                            e.printStackTrace();
                            return null;
                        }
                    })
                    .filter(dto -> dto != null)
                    .collect(Collectors.toList());

            results.sort(Comparator.comparingDouble(JinhuaProjectDto::getSimilarityScale).reversed());

            //可能会出现文件比对结果小于三份的
            List<JinhuaProjectDto> topThree;
            if (results.size()<3){
                topThree = results.subList(0, Math.min(results.size(), results.size()));
            }else {
                topThree = results.subList(0, Math.min(3, results.size()));
            }

            for (JinhuaProjectDto jinhuaProjectDto : topThree) {

                //根据项目id去奥技能筛选数据
                String projectId = jinhuaProjectDto.getProjectId();

                //这里再次过滤一下，因为奥技能有脏数据
                if (projectId.length()>=32){
                    ProjectResultObj ajnProjectList = projectService.getAJNProjectList(projectId);
                    List<ThingProjectData> projectDataList = ajnProjectList.getData().getData();
                    if (!CollectionUtils.isEmpty(projectDataList)){
                        //这里本来就应该只返回一个对象，因为有脏数据
                        ThingProjectData projectData = projectDataList.get(0);
                        jinhuaProjectDto.setName(projectData.getName());
                        jinhuaProjectDto.setUnitName(projectData.getUnitName());
                        jinhuaProjectDto.setUnitDdId(projectData.getUnitDdId());
                        jinhuaProjectDto.setID(projectData.getId());
                        jinhuaProjectDto.setCheckMoney(projectData.getCheckMoney());
                        jinhuaProjectDto.setReportMoney(projectData.getReportMoney());
                    }
                }
                sortedSet.add(jinhuaProjectDto);

            }
/*            long endTime = System.currentTimeMillis();
            long elapsedTime = endTime - startTime;
            System.out.println("API call took " + elapsedTime + " milliseconds");*/

//            List<Double> maxThree = findMaxThree(sortedSet);

//            hubConnectionManager.verifyTokenAndUpdateConnection();
        return R.ok().put("data",sortedSet);
        }
        catch (Exception e) {
            throw new Exception(e);
        }

    }

    public static List<Double> findMaxThree( List<Double> numbers) {
        List<Double> maxThree = new ArrayList<>();

        if (numbers.size() < 3) {
            maxThree.addAll(numbers);
        } else {
            Collections.sort(numbers, Collections.reverseOrder());
            maxThree.addAll(numbers.subList(0, 3));
        }

        return maxThree;
    }

/*    @PostMapping("/find")
    public R find(@RequestParam("id") Integer id){
        ProjectFileEntity byId = projectFileService.findById(id);
        if (byId.getState()==ProcessingState.PROCESSING.getValue() || byId.getState()==ProcessingState.PENDING.getValue()){
            //比对未完成和待处理，没有前端继续轮询
            return R.error("未完成比对");
        }
        //最多相似的文件id
        Integer maxSimilarityHistoryFileId = byId.getMaxSimilarityHistoryFileId();
        if (maxSimilarityHistoryFileId==0){
            return R.error("没有相似的文件，或者文件为空无法比对");
        }
        //第二个文件相识id
        Integer secondSimilarityHistoryFileId = byId.getSecondSimilarityHistoryFileId();
        Integer thirdSimilarityHistoryFileId = byId.getThirdSimilarityHistoryFileId();

        List<Integer> similarityHistoryFileIds = new ArrayList<>();
        similarityHistoryFileIds.add(maxSimilarityHistoryFileId);
        if (secondSimilarityHistoryFileId!=0){
            similarityHistoryFileIds.add(secondSimilarityHistoryFileId);
        }
        if (thirdSimilarityHistoryFileId!=0){
            similarityHistoryFileIds.add(thirdSimilarityHistoryFileId);
        }
        List<CompareVo> compareVos = new ArrayList<>();
        for (Integer similarityHistoryFileIdItem:similarityHistoryFileIds) {
            CompareVo compareVo = new CompareVo();
            HistoryFileEntity historyFileEntity = historyFileService.findById(similarityHistoryFileIdItem);
            Integer fileId = historyFileEntity.getFileId();

            JinhuaFile jinhuaFile = jinhuaFileService.selectJinhuaFileByFileId(fileId);
            JinhuaProject jinhuaProject = jinhuaProjectService.selectJinhuaProjectByProjectId(jinhuaFile.getProjectId());

            compareVo.setId(similarityHistoryFileIdItem);
//            compareVo.setFailureReason(byId.getFailureReason());
            compareVo.setFileName(historyFileEntity.getFileName());

            float similarity = similarityHistoryFileIdItem;
            compareVo.setMaxSimilarity(similarity / 1000000);

            compareVo.setProjectName(jinhuaProject.getName());
            compareVo.setReportMoney(jinhuaProject.getReportMoney());
            compareVo.setCheckMoney(jinhuaProject.getCheckMoney());
            compareVo.setUnitName(jinhuaProject.getUnitName());
            compareVo.setUnitDdId(jinhuaProject.getUnitDdId());
            compareVos.add(compareVo);
        }
 *//*       byte[] fileContent = new byte[0];
        try {
            fileContent = Files.readAllBytes(Paths.get(historyFileEntity.getFilePath()));
            compareVo.setFile(fileContent);*//*
//        } catch (IOException e) {
//            e.printStackTrace();
//        }

        return R.ok("完成比对结果").put("data",compareVos);
    }*/

/*    @GetMapping("/download")
    @ResponseBody
    public ResponseEntity<FileSystemResource> downloadFile(@RequestParam("id") Integer id) throws UnsupportedEncodingException {

        HistoryFileEntity historyFileEntity = historyFileService.findById(id);


        // 拼接文件路径，根据你的数据库中的文件路径字段拼接
        String filePath = historyFileEntity.getFilePath();

        // 对文件名进行URL编码
        String encodedFilename = URLEncoder.encode(historyFileEntity.getFileName(), "UTF-8");

        // 创建一个文件系统资源
        FileSystemResource file = new FileSystemResource(filePath);

        // 设置下载的HTTP头部信息
        HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + encodedFilename);

        // 设置响应类型为"application/octet-stream"，表示二进制流
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);

        // 返回ResponseEntity，包含文件内容和头部信息
        return ResponseEntity.ok()
                .headers(headers)
                .body(file);
    }*/

    public static void main(String[] args) {
        SortedSet<Integer> sortedSet = new TreeSet<>();

        sortedSet.add(5);
        sortedSet.add(2);
        sortedSet.add(8);
        sortedSet.add(1);
        sortedSet.add(10);
        sortedSet.add(5); // Adding a duplicate element

        // The sortedSet now contains the elements in sorted order, allowing duplicates
        for (Integer num : sortedSet) {
            System.out.println(num);
        }
    }
}
